using System;
using NUnit.Framework;
using PhillyCodeCamp.Domain;
using PhillyCodeCamp.Services;
using PhillyCodeCampSpecs.Helpers;

namespace PhillyCodeCampSpecs.Domain
{
    [TestFixture]
    public class when_no_income_has_been_earned
    {
        [Test]
        public void should_calculate_no_tax()
        {
            const decimal income = 0;
            const string usState = "";
            const decimal stateTaxRate = 0;
            const decimal usTaxRate = 0;
            var submissionDate = new DateTime(2009, 4, 12);
            const bool isBailedOut = false;
            var taxRateService = ObjectMother.CreateTaxRateService(stateTaxRate, usTaxRate);
            var systemUnderTest = new 
                TaxReturn(income, usState, submissionDate, isBailedOut, taxRateService);

            var tax = systemUnderTest.ComputeStateTax();

            Assert.AreEqual(tax, 0);
        }
    }

    [TestFixture]
    public class when_100_dollars_is_earned
    {
        private decimal _income;
        private TaxReturn _systemUnderTest;

        [Test]
        public void state_tax_should_be_10_dollars_if_state_tax_rate_is_10_percent()
        {
            var stateTax = _systemUnderTest.ComputeStateTax();

            Assert.AreEqual(stateTax, 10m);
        }

        [Test]
        public void us_tax_should_be_20_dollars_if_state_tax_rate_is_20_percent()
        {
            var usTax = _systemUnderTest.ComputeUsTax();

            Assert.AreEqual(usTax, 20m);
        }

        [Test]
        public void total_tax_should_total_state_tax_plus_us_tax()
        {
            var usTax = _systemUnderTest.ComputeTax();

            Assert.AreEqual(usTax, 30m);
        }

        [TestFixtureSetUp]
        public void Context ()
        {
            _income = 100;
            const string usState = "state";
            const decimal stateTaxRate = .1m;
            const decimal usTaxRate = .2m;
            const bool isBailedOut = false;
            var submissionDate = new DateTime(2009, 4, 12);

            var stubTaxRateService = ObjectMother.CreateTaxRateService(stateTaxRate, usTaxRate);

            _systemUnderTest = new TaxReturn(_income, usState, submissionDate,isBailedOut, stubTaxRateService);
            
        }
    }
    [TestFixture]
    public class when_late_penalty_has_occurred
    {
        private decimal _income;
        private TaxReturn _systemUnderTest;

        [Test]
        public void total_tax_should_multiplied_by_late_penalty_rate()
        {
            Assert.AreEqual(_systemUnderTest.ComputeTax(), 60M);
        }

        [TestFixtureSetUp]
        public void Context()
        {
            _income = 100;
            const string usState = "state";
            const decimal stateTaxRate = .1m;
            const decimal usTaxRate = .2m;
            var submissionDate = new DateTime(2009, 4, 12); //does not factor into this test
            const bool isBailedOut = false;
            var stubTaxRateService =
                ObjectMother.CreateTaxServiceWith100PercentLatePenalty(stateTaxRate, usTaxRate);

            _systemUnderTest = new TaxReturn(_income, usState, submissionDate, isBailedOut, stubTaxRateService);

        }
    }

    [TestFixture]
    public class when_a_person_is_an_executive_in_a_bailed_out_company
    {
        private decimal _income;
        private TaxReturn _systemUnderTest;

        [Test]
        public void total_tax_should_equal_total_income()
        {
            Assert.AreEqual(_systemUnderTest.ComputeTax(), _income);
        }

        [TestFixtureSetUp]
        public void Context()
        {
            _income = 100;
            const string usState = "state";
            const decimal stateTaxRate = .1m;
            const decimal usTaxRate = .2m;
            var submissionDate = new DateTime(2009, 4, 12); //does not factor into this test
            const bool isBailedOut = true;
            var stubTaxRateService =
                ObjectMother.CreateTaxRateService(stateTaxRate, usTaxRate);

            _systemUnderTest = new TaxReturn(_income, usState, submissionDate, isBailedOut, stubTaxRateService);

        }
    }

}